package com.zephyr.nio;

import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;

public class SocketIO {

    private static final int PORT = 8888;

    @Test
    public void client() throws Exception {
        SocketChannel sChannel = SocketChannel.open(new InetSocketAddress("127.0.0.1", PORT));
        System.out.println("连接成功");
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {
            String next = sc.next();
            buffer.put(("客户端说:" + next).getBytes());
            buffer.flip();
            sChannel.write(buffer);
            buffer.clear();
        }
        sc.close();
        sChannel.close();
    }

    @Test
    public void blockingServer() throws IOException {
        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        ssChannel.bind(new InetSocketAddress(PORT));
        SocketChannel sChannel = ssChannel.accept();
        System.out.println("新的连接：" + sChannel.getRemoteAddress());
        ByteBuffer buf = ByteBuffer.allocate(1024);
        int len;
        while ((len = sChannel.read(buf)) > 0) {
            buf.flip();
            System.out.println(new String(buf.array(), 0, len));
            buf.clear();
        }
    }

    @Test
    public void nonBlockingServer() throws IOException {
        ServerSocketChannel ssChannel = ServerSocketChannel.open();
        ssChannel.configureBlocking(false);
        ssChannel.bind(new InetSocketAddress(PORT));
        Selector selector = Selector.open();
        ssChannel.register(selector, SelectionKey.OP_ACCEPT);
        while (selector.select() > 0) {
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()) {
                SelectionKey sk = iterator.next();
                if (sk.isAcceptable()) {
                    SocketChannel sChannel = ssChannel.accept();
                    System.out.println("新的连接：" + sChannel.getRemoteAddress());
                    sChannel.configureBlocking(false);
                    sChannel.register(selector, SelectionKey.OP_READ);
                } else if (sk.isReadable()) {
                    SocketChannel sChannel = (SocketChannel) sk.channel();
                    ByteBuffer buf = ByteBuffer.allocate(1024);
                    int len;
                    while ((len = sChannel.read(buf)) > 0) {
                        buf.flip();
                        System.out.println(new String(buf.array(), 0, len));
                        buf.clear();
                    }
                }
            }
            iterator.remove();
        }
    }

}
